
/*
 * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
 *
 * (b)  If this Sample Code is distributed as part of the Display PostScript
 *	System Software Development Kit from Adobe Systems Incorporated,
 *	then this copy is designated as Development Software and its use is
 *	subject to the terms of the License Agreement attached to such Kit.
 *
 * (c)  If this Sample Code is distributed independently, then the following
 *	terms apply:
 *
 * (d)  This file may be freely copied and redistributed as long as:
 *	1) Parts (a), (d), (e) and (f) continue to be included in the file,
 *	2) If the file has been modified in any way, a notice of such
 *      modification is conspicuously indicated.
 *
 * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
 *	Adobe Systems Incorporated.
 * 
 * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
 *	CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
 *	AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
 *	ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
 *	OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
 *	WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
 *	WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
 *	DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
 *	FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
 *	OF THIRD PARTY RIGHTS.
 */

/*
 *	DetectApp.m
 *
 *	This subclass of the application class performs the global
 *	setup needed for the HitDetection application. The drawing
 *	window is created as well as the window buffers for redrawing
 *	and moving.
 *
 *	Version:	2.0
 *	Author:	Ken Fromm
 *	History:
 *			03-07-91		Added this comment.
 */

#import "DetectApp.h"
#import "DrawingView.h"
#import "DrawingViewWraps.h"
#import "DocView.h"
#import "ScrollingView.h"
#import <appkit/Matrix.h>
#import <appkit/ScrollView.h>
#import <appkit/ClipView.h>
#import <appkit/Window.h>
#import "HitPointView.h"
#import <appkit/nextstd.h>

static NXRect			drawingRect = {0, 0, 612, 792};
static NXRect			windowRect = {315, 270, 450, 500};

/*
*	Create a plain window the size of the rectangle passed in and
*	then insert a view into the window as a subview. A clip view
*	is swapped for the content view if addclipview is YES. The
*	ClipView is used for the alpha buffer, which holds the primary
*	drawing. The beta buffer does not need to scroll so a ClipView
*	is unnecessary.
*/
static id createBuffer(const NXRect *winRect, BOOL  addclipview)
{
	id		buffer, clipview, window;

	NXRect	contRect;
	
	contRect.origin.x = contRect.origin.y = 0;
	contRect.size = winRect->size;
	window = [[Window alloc]  initContent:&contRect
				style:NX_PLAINSTYLE
				backing:NX_RETAINED
				buttonMask:0
				defer:NO] ;

	buffer = [[[[View  alloc]  initFrame:&contRect] allocateGState] setClipping:NO];
	if (addclipview)
	{	
		clipview = [[[ClipView  alloc]  init] setFlipped:NO];
		[clipview  setDisplayOnScroll:NO];
		[[window  setContentView:clipview ] free];
		[clipview  setDocView:buffer];
	}
	else
		[[window contentView] addSubview:buffer];
	
	[window  display];

	return buffer;
}

/* Resize the buffers and their windows. Called when the window resizes. */
static void resizeBuffer(id buffer, const NXSize*newSize)
{
	NXRect		oldSize;
	
	[[buffer superview]  getFrame:&oldSize];
	if (newSize->width > oldSize.size.width || newSize->height > oldSize.size.height)
	{
		[[buffer window]  sizeWindow:newSize->width :newSize->height];
		[buffer sizeTo:newSize->width :newSize->height];
	}
}

@implementation DetectApp

+ new
{
	self = [super new];

	hitsetting = 4.0;

	return self;
}

/*
*	Create the drawing window and place a scrollview as the content view.
*	A DocView  instance is placed as the document view of the ClipView and then
*	a DrawingView instance is placed as a subview of DocView. The DocView
*	places the drawing view in the center of the window and draws the border
*	and the drop shadow when the drawing view is reduced and made smaller
*	than the size of the clip view. (The application is made the delegate of
*	the window in order to intercept the windowDidResize message and 
*	resize the buffers.)
*/
- createWindow:(NXRect *) winRect
{
	id		scrollView, docView;

	NXRect	tempRect;

	windowId = [[Window alloc]  initContent:winRect
			style:NX_TITLEDSTYLE
			backing:NX_BUFFERED
			buttonMask:NX_RESIZEBUTTONMASK
			defer:NO];
	[windowId  setTitle:"Hit Detection"];

	[Window  getContentRect:&tempRect  forFrameRect:winRect  style:NX_TITLEDSTYLE];
	scrollView = [[ScrollingView alloc]  initFrame:&tempRect];
	[scrollView setBorderType:SCROLLVIEW_BORDER];

	drawingviewId = [[DrawingView  alloc]  initFrame:&drawingRect];
	docView = [[[[DocView alloc]  init]  setClipping:NO] setScale:1.0];
	[scrollView  setDocView:docView];
	[[docView  superview]  setFlipped:NO];
	[docView  addDrawView:drawingviewId];

	[docView  placeView:drawingviewId];
	[drawingviewId  createObject];

	[[windowId  setContentView:scrollView] free];

	[windowId  addToEventMask:WINDOW_MASK];
	[windowId  makeFirstResponder:drawingviewId];
	[windowId  setDelegate:self];

	return self;
}

/* The window will free the its subviews. */
- free
{
	[[bufferalphaId  window]  free];
	[[bufferbetaId  window]  free];
	[windowId  free];

	return [super free];
}

- getBufferAlpha
{
	return bufferalphaId;
}

- getBufferBeta
{
	return bufferbetaId;
}

- getDrawingView
{
	return drawingviewId;
}

/* 
*	Places the buffers onscreen when the menu item is selected.
*	Strictly for instructional purposes only.
*/
- showBuffers:sender
{
	if (!showbuffers)
	{
		[[bufferalphaId window]  orderWindow:NX_ABOVE
			relativeTo:[windowId windowNum]];
		[[bufferalphaId window] moveTo:10 :10];
		[[bufferbetaId window]  orderWindow:NX_ABOVE
			relativeTo:[windowId windowNum]];
		[[sender selectedCell] setTitle:"Hide Buffers"];
		[[bufferbetaId window] moveTo:560 :10];
	}
	else
	{
		[[bufferalphaId window]  orderOut:self];
		[[bufferbetaId window]  orderOut:self];
		[[sender selectedCell] setTitle:"Show Buffers"];
	}
	showbuffers = !showbuffers;

	return self;
}

- showWindow:sender
{
	return [windowId  makeKeyAndOrderFront:self];
}

/*	Sets the hit setting to the value. */
- setHitSetting:(float) value
{	
	hitsetting = value;

	return self;	
}

/*
*	Returns an unscaled the hit setting.
*/
- (float) hitSetting
{	
	return hitsetting;
}

/*
 * Resizes the doc view and repositions the drawing view inside the doc view.
 */
- windowDidResize:sender
{
	NXSize		contSize;
	
	[[windowId  contentView]  getContentSize:&contSize];
	resizeBuffer(bufferalphaId, &contSize);
	resizeBuffer(bufferbetaId, &contSize);

	[[drawingviewId  superview]  placeView:drawingviewId];
	
	return self;
}

- appDidInit:sender
{
	bufferalphaId = createBuffer(&windowRect, YES);
	bufferbetaId = createBuffer(&windowRect, NO);

	[self  createWindow:&windowRect];
	[windowId display];
	[windowId makeKeyAndOrderFront:self];

	return self;
}

@end

